
#include "bignum.h"

void
bignum::init (void)
{

  for (int i = 0; i < MAX_DIGITS; i++)
    digits[i] = 0;

}

void
bignum::normalize (void)
{

  for (int i = 0; i < MAX_DIGITS-1; i++)
    if (digits[i] >= 10)
     {
      digits[i+1] += digits[i] / 10;
      digits[i] = digits[i] % 10;
     }

  // Note, this does not detect overflow
}


// Simply initialize the number to 0.
bignum::bignum (void)
{

  init ();

}


// Initializes the number from an integer -- just calculates each decimal
// place by successively dividing by 10 and putting the remainder in
// the 'digits' array.
bignum::bignum (int i)
{

  int place = 0;

  init();

  while (i)
   {
    digits[place] = i % 10;
    place++;
    i /= 10;
   }

}

// This initializes the bignum from a string.  It is assumed to be a string
// of the form "343996919994994" -- only digits.  We use strlen() to figure
// the power of 10 represented by the first digit of the number.
bignum::bignum (const char *i)
{

  int place;

  init ();

  place = strlen (i) - 1;

  while (*i)
   {
    digits[place] = *i - '0';;
    i++;
    place--;
  }

}


// Overloaded "+" operator: we just add each digit from the two operands
// and put the result in a new bignum; then call normalize.
bignum bignum::operator+ (const bignum &b)
{

  bignum result;

  for (int i = 0; i < MAX_DIGITS; i++)
    result.digits[i] = digits[i] + b.digits[i];

  result.normalize ();

  return result;

}


// Put the text representation of our number into a string buffer.    
char *bignum::print (void)
{

  int printing = 0;
  char *ptr = print_buffer;

  for (int i = MAX_DIGITS-1; i >= 0; i--)
   {
    // Don't print leading 0's
    if (digits[i] != 0)
      printing = 1;

    // If we're past leading 0's, start output
    if (printing)
      *(ptr++) = digits[i] + '0';
   }

  // If the number is 0, print a 0 anyway
  if (!printing)
    *(ptr++) = '0';

  // Add a null to terminate the string
  *ptr = '\0';

  return print_buffer;

}

std::ostream &operator << (std::ostream &s, bignum b)
{

  s << b.print ();
  return s;

}
  
